package com.xunqi.common.auth;

import com.xunqi.common.util.JwtOperator;
import io.jsonwebtoken.Claims;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Objects;

/**
 * @Description:
 * @Created with IntelliJ IDEA.
 * @author: 夏沫止水
 * @create: 2020-04-17 15:32
 **/
@Aspect
@Component
public class AuthAspect {

    @Resource
    private JwtOperator jwtOperator;


    @Around("@annotation(com.xunqi.common.auth.CheckLogin)")
    public Object checkLogin(ProceedingJoinPoint point) throws Throwable {
        checkToken();
        return point.proceed();
    }


    @Around("@annotation(com.xunqi.common.auth.CheckAuthorization)")
    public Object checkAuthorization(ProceedingJoinPoint point) throws Throwable {

        try {
            //1.效验token是否合法
            this.checkToken();

            //2.验证用户角色是否匹配
            HttpServletRequest request = this.getHttpServletRequest();
            String role = (String) request.getAttribute("role");

            MethodSignature signature = (MethodSignature)point.getSignature();
            Method method = signature.getMethod();
            CheckAuthorization annotation = method.getAnnotation(CheckAuthorization.class);

            String value = annotation.value();

            if (!Objects.equals(role,value)) {
                throw new SecurityException("用户无权访问！");
            }

        } catch (Throwable throwable) {
            throw new SecurityException("用户无权访问!",throwable);
        }

        return point.proceed();
    }


    /**
     * 验证token
     */
    public void checkToken() {

        try {
            HttpServletRequest request = this.getHttpServletRequest();
            String token = request.getHeader("X-Token");

            //2.效验token是否合法&是否过期，如果不合法或者已过期，直接抛异常；如果合法放行
            Boolean isValid = jwtOperator.validateToken(token);

            //如果不合法就抛异常
            if (!isValid) {
                throw new SecurityException("Token不合法");
            }

            //3.如果效验成功，那么就将用户的信息设置到request的attribute里面
            Claims claimsFromToken = jwtOperator.getClaimsFromToken(token);

            request.setAttribute("id",claimsFromToken.get("id"));
            request.setAttribute("wxNickName",claimsFromToken.get("wxNickName"));
            request.setAttribute("role",claimsFromToken.get("role"));
        } catch (Throwable throwable) {
            throw new SecurityException("Token不合法");
        }

    }


    /**
     * 从header里获取token
     * @return
     */
    public HttpServletRequest getHttpServletRequest() {

        //1.从header里获取token
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();

        ServletRequestAttributes attributes = (ServletRequestAttributes) requestAttributes;

        HttpServletRequest request = attributes.getRequest();

        return request;
    }


}
